<?php
include "common.php";
error_reporting(0);
$port = 8989;
   
// create a streaming socket, of type TCP/IP
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// set the option to reuse the port
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);

// "bind" the socket to the address to "localhost", on port $port
// so this means that all connections on this port are now our resposibility to send/recv data, disconnect, etc..
socket_bind($sock, 0, $port);

// start listen for connections
socket_listen($sock);

// create a list of all the clients that will be connected to us..
// add the listening socket to this list
$clients = array($sock);

while (true) {
    // create a copy, so $clients doesn't get modified by socket_select()
    $read = $clients;
   
    // get a list of all the clients that have data to be read from
    // if there are no clients with data, go to next iteration
    if (socket_select($read, $write = NULL, $except = NULL, 0) < 1)
        continue;
   
    // check if there is a client trying to connect
    if (in_array($sock, $read)) {
        // accept the client, and add him to the $clients array
        $clients[] = $newsock = socket_accept($sock);
       
        // send the client a welcome message
        socket_write($newsock, "no noobs, but ill make an exception :)\n".
        "There are ".(count($clients) - 1)." client(s) connected to the server\n");
       
        socket_getpeername($newsock, $ip);
        echo "New client connected: {$ip}\n";
       
        // remove the listening socket from the clients-with-data array
        $key = array_search($sock, $read);
        unset($read[$key]);
    }
   
    // loop through all the clients that have data to read from
    foreach ($read as $read_sock) {
        // read until newline or 1024 bytes
        // socket_read while show errors when the client is disconnected, so silence the error messages
        $data = @socket_read($read_sock, 1024, PHP_NORMAL_READ);
        
        // check if the client is disconnected
        if ($data === false) {
            // remove client for $clients array
            $key = array_search($read_sock, $clients);
            unset($clients[$key]);
            //echo "client disconnected.\n";
            // continue to the next client to read from, if any
            continue;
        }
       	$data = decode($send_sock);
        rpc_server($data);
       
    } // end of reading foreach
}

// close the listening socket
socket_close($sock);


function rpc_server($buf) {
	$classRet = preg_match('/Rpc-Class:\s(.*);/i', $buf, $class);
    $methodRet = preg_match('/Rpc-Method:\s(.*);/i', $buf, $method);
    $paramsRet = preg_match('/Rpc-Params:\s(.*);/i', $buf, $params);

     if($classRet && $methodRet) {
        $class = ucfirst($class[1]);
        $file = $realPath . '/' . $class . '.php';
        //判断文件是否存在，如果有，则引入文件
        if(file_exists($file)) {
            require_once $file;
            //实例化类，并调用客户端指定的方法
            $obj = new $class();
            //如果有参数，则传入指定参数
            if(!$paramsRet) {
                $data = $obj->$method[1]();
            } else {
                $data = $obj->$method[1](json_decode($params[1], true));
            }
            //把运行后的结果返回给客户端
            fwrite($conn, encode($data));
        } else {
            fwrite($conn, encode("class or method error"));
        }
	} else {
	    fwrite($conn, encode("class or method error"));
	}
}